#pragma once
#include<tuple>

template<typename T>
T& of(T& t){
    return t;
}

// template<typename... Types>
// void print(const Types&... args) {
//    ( (std::cout<<args<<std::endl), ...);
//     // print(args...);
// }

//https://blog.csdn.net/qq_21438461/article/details/131417769
// template <typename Tuple, std::size_t... Indices>
// void print_tuple_impl(const Tuple& t, std::index_sequence<Indices...>) {
//     ((std::cout<< std::get<Indices>(t) &&  cout<<std::endl), ...);
// }

//https://blog.csdn.net/qq_35487973/article/details/121532038
// void print(){}

// template<typename T, typename... Types>
// void print(const T& first, const Types&... args){
//     cout << first << "\t end:" << endl;
//     print(args...);
// }

// template <typename F, typename T, std::size_t... Indices>
// void print_tuple(F& f, T t1, T t2, std::index_sequence<Indices...> ){
//     //((std::cout<< std::get<Indices>(t) &&  cout<<std::endl), ...);
//     (f(std::get<Indices>(t1), std::get<Indices>(t2)), ...); 
// }


// void testArgs(){
//     // print<1,2,3>( std::make_index_sequence(sizeof...(args) ));
//     // print(1,2,3);
//     // print_tuple_impl(t1, std::make_index_sequence<std::tuple_size<decltype(t1)>::value >());

//     std::tuple<int, std::string, float> t1(10, "Test", 3.14f);
//     std::tuple<int, std::string, float> t2(10, "Test", 3.14f);
    
//     auto f =[] (auto& t1, auto& t2){
//          cout<<t1 <<"==" <<t2<< std::endl;
//     };

//     constexpr  int size = std::tuple_size<decltype(t1)>::value;
//     print_tuple(f,t1,t2,std::make_index_sequence<size>{});
//     // 
// }